package com.hd.boot0407.controller;

import cn.hutool.captcha.LineCaptcha;
import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.kaptcha.Kaptcha;
import com.github.pagehelper.PageInfo;
import com.hd.boot0407.entity.User;
import com.hd.boot0407.service.UserService;
import com.hd.boot0407.util.Constants;
import com.hd.boot0407.vo.ResultVo;
import com.hd.boot0407.vo.TableVo;
import com.hd.boot0407.vo.UserPicVo;
import com.hd.boot0407.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Slf4j//打印日志
@RestController
@RequestMapping("/user")
public class UserController {
    @Value("${file.upload.path}")
    String fileUploadPath;
    @Autowired
    UserService userService;
    @Value("${file.export.path}")
    String fileExportPath;
    @GetMapping("/clearExport")
    public ResultVo clearExport(){
        File file = new File(fileExportPath);
        File[] files = file.listFiles();
        for (File file1 : files) {
            file1.delete();
        }
        if (files==null) {
            //file.delete();
            return ResultVo.ok("删除全部文件成功");
        }
        return ResultVo.ok("删除全部文件失败");
    }
    @GetMapping("/clearUserPic")
    public ResultVo clearUserPic(){
        File file = new File(fileUploadPath);
        //获取当前目录下的所有内容（返回字符串类型的文件名列表）
        String[] list = file.list();
        for (String name : list) {
            System.out.println(name);
            if (userService.getByFileName(name).size()==0){
                String path=fileUploadPath + name;
                File file1 = new File(path);
                System.out.println(file1+(file1.delete() == true ? "删除成功" : "删除失败"));

            }
        }
        return ResultVo.ok("删除全部无用头像成功");
    }

    @PostMapping("/upload")
    public ResultVo upload(MultipartFile file) throws Exception {
        log.debug("入参为—file={}",file);
        userService.batchInsert(file);
        return ResultVo.ok("批量插入成功");
    }

    @GetMapping("/export")
    public HashMap<String, Object> export() throws IOException {
        String filename = userService.export();
        HashMap<String,Object> map = new HashMap<>();
        map.put("data",filename);
        return map;
    }
    @GetMapping("/logout")
    public void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {

        // 1. 清空session中的用户登录信息
        final HttpSession session = request.getSession();
        session.setAttribute(Constants.USER_SESSION_KEY,null);
        // 2. 清空浏览器端的Cookie ,  就是把要删除的cookie的 age设置为0
        final Cookie cookie = new Cookie(Constants.USER_AUTOLOGIN_TOKEN, null);
        cookie.setPath("/");
        cookie.setMaxAge(0);
        response.addCookie(cookie);
        // 3. 重定向到 login.html
        response.sendRedirect("/login.html");
    }

    @RequestMapping("/currentUser")
    public UserPicVo currentUser(HttpSession session, HttpServletRequest request){
        // 从session中获取用户信息 ，放入ResultVO返回
        UserPicVo userPicVo = new UserPicVo();
        Object userName = session.getAttribute("userName");
        if (userName==null) {
            User user = (User) session.getAttribute("user");
            userName = user.getName();
        }
        System.out.println("查询到的用户名："+userName);
        User user1 = userService.getByName((String) userName);
        System.out.println(user1.getFilename());
        if (user1.getFilename()==null) {
            user1.setFilename("孙悟空.jpg");
        }
        userPicVo.setName(user1.getName());
        //获取本地路径
        String filePath ="D:/imgCode/"+user1.getFilename();
        userPicVo.setFilepath(filePath);
        return userPicVo;
    }
    @RequestMapping("/pic")
    public void getUserPic(String filepath, HttpServletRequest request, HttpServletResponse response) {
        //final String realPath =fileUploadPath;

        //根据传入的图片文件路径，加载图片并返回
        try {
            IOUtils.copy(new FileInputStream(filepath), response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*增加接口*/
    @PostMapping ("/add")

    public TableVo<User> addUser(String name, String password, String sex, @DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday, @DateTimeFormat(pattern = "yyyy-MM-dd")Date registTime){
        log.debug("{},{},{},{},{}",name,password,sex,birthday,registTime);
        User user = new User(name,password,sex,birthday,registTime);
        /*密码加密处理*/
        final String md5password = DigestUtil.md5Hex(user.getPassword());
        TableVo<User> userTableVo = new TableVo<>();
        user.setPassword(md5password);
        if (userService.addUser(user) == 1) {
            userTableVo.setCode("1");
        } else {
            userTableVo.setMsg("添加失败");
        }
        return userTableVo;
    }
    @PostMapping(value = "/update")
    public TableVo<User> update(Integer id,String name,String password,String sex,@DateTimeFormat(pattern = "yyyy-MM-dd")Date birthday,@DateTimeFormat(pattern = "yyyy-MM-dd")Date registTime){
        log.debug("更新={},{},{},{},{}",name,password,sex,birthday,registTime);
        User user = new User(id,name,password,sex,birthday,registTime);
        /*密码加密处理*/
        final String md5password = DigestUtil.md5Hex(user.getPassword());
        user.setPassword(md5password);
        TableVo<User> userTableVo = new TableVo<>();
        if (userService.updateUser(user)== 1) {
            userTableVo.setCode("1");
        } else {
            userTableVo.setMsg("修改失败");
        }
        return userTableVo;
    }
    @PostMapping(value = "/del")
    public TableVo<User> del(Integer[] ids,HttpSession session) throws IOException {
        TableVo<User> userTableVo = new TableVo<>();
        log.debug("删除的id={}",ids);
        if (userService.DeleteByIdArr(ids) >= 1) {
            userTableVo.setCode("1");
        } else {
            userTableVo.setMsg("删除失败");
        }
        return userTableVo;
    }
    @GetMapping("/getallByPageHelpler")
    public TableVo<User> getallByPageHelpler(Integer page, Integer limit,
                                             String username, String sex, @DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){

//        PageInfo<User> pageInfo = userService.getallByPageHelpler(page,limit);
        PageInfo<User> pageInfo = userService.getallByPageHelpler(page,limit,username,sex,birthday);

        TableVo<User> userTableVo = new TableVo<>();
        userTableVo.setCode("0");
        userTableVo.setMsg("ok");
        userTableVo.setCount(Integer.valueOf(pageInfo.getTotal()+""));
        userTableVo.setData(pageInfo.getList());

        return userTableVo;

    }


    @GetMapping("/getallByPage")
    public TableVo<User> getallByPage(Integer page, Integer limit){

        Integer count = userService.getTotalCount();

        List<User> userList = userService.getallByPage(page,limit);

        TableVo<User> userTableVo = new TableVo<>();
        userTableVo.setCode("0");
        userTableVo.setMsg("ok");
        userTableVo.setCount(count);
        userTableVo.setData(userList);

        return userTableVo;

    }

    @GetMapping("/getById")
    public User getById(Integer id) {
        System.out.println(id);
        return userService.getById(id);
    }

    @GetMapping("/getByName")
    public User getByName(String name) {
        return userService.getByName(name);
    }

    @GetMapping("/page")
    public PageInfo<User> page(int pageNum, int pageSize) {
        return userService.selectAll(pageNum, pageSize);
    }

    @GetMapping(value = "/DeleteById", produces = "text/html; charset=UTF-8")
    public String DeleteById(Integer id) {
        return userService.DeleteById(id) == 1 ? "删除成功" : "删除失败";
    }

    @GetMapping(value = "/DeleteByIdArr", produces = "text/html; charset=UTF-8")
    public String DeleteByIdArr(Integer[] id) {
        return userService.DeleteByIdArr(id) == 1 ? "删除成功" : "删除失败";
    }

    /*@GetMapping(value = "/add", produces = "text/html; charset=UTF-8")
    public String add(User user) {
        return userService.addAutoIdUser(user) == 1 ? "添加成功" : "添加失败";
    }
    @GetMapping(value = "/update", produces = "text/html; charset=UTF-8")
    public String update(User user) {
        return userService.updateUser(user) == 1 ? "修改成功" : "修改失败";
    }
*/
    //如何设计登录接口
    //前端需求的字段，code , message

    @PostMapping("login")
    public ResultVo login(String name, String password, String capchar,String mlogin, HttpSession session, HttpServletResponse response) {
        final LineCaptcha captcha = (LineCaptcha) session.getAttribute(Constants.HUTOOL_SESSION_KEY);
        log.debug("是否免登录={}",mlogin);
        System.out.println(captcha);
        final ResultVo resultvo = new ResultVo();
        //1.对于接收到的参数进行必要的校验
        //2.调用service层的对象，完成具体的业务逻辑处理
        /*
        //自己写的
        User byName = userService.getByName(name);
        System.out.println(captcha);
        判断用户是否当前已登录
        if (!byName.getStatus().equals("1")) {
            if (capchar != null && capchar.equals(captcha)) {
                if (byName == null) {
                    //3。根期service返网的结果，封装ResultVo
                    resultvo.setCode("-1");
                    resultvo.setMessage("用户不存在");
                } else if (!byName.getPassword().equals(password)) {
                    //3。根期service返网的结果，封装ResultVo
                    resultvo.setCode("-1");
                    resultvo.setMessage("密码输入错误！");
                } else {
                    //3。根期service返网的结果，封装ResultVo
                    byName.setStatus("1");
                    userService.updateUser(byName);
                    resultvo.setCode("1");
                }
            } else {
                //3。根期service返网的结果，封装ResultVo
                resultvo.setCode("-1");
                resultvo.setMessage("验证码错误");
            }

        }else {
            //3。根期service返网的结果，封装ResultVo
            resultvo.setMessage("当前用户已登录,不可重复登录");
            resultvo.setCode("-1");
        }*/
        //跟老师写的
        // 1. 验证码校验
        log.debug("接收到参数，username={}，password={}，code={}",name,password,capchar);
        if (capchar == null || !captcha.verify(capchar)) {
            log.debug("验证码校验失败----->sesson中的验证码为{},传入的验证码为{}",captcha,capchar);
            resultvo.setCode("-1");
            resultvo.setMessage("验证码错误");
            return resultvo;
        }
        //2.调用service层的对象，完成具体的业务逻辑处理
        User user =userService.login(name,password);
        // 3. 封装返回值ResultVo对象
        if (user==null){
            resultvo.setCode("-1");
            resultvo.setMessage("用户名或密码错误");
        }else {
            // 如果user为空，意味登录失败
            if (mlogin!=null) {
                resultvo.setCode("1");
                // 创建cookie并将成功登陆的用户保存在里面
                Cookie cookie = new Cookie("usertoken", name + "-" + password);
                /*设置跨域*/
                cookie.setPath("/");
                cookie.setMaxAge(1209600); // 设置两周有效
                response.addCookie(cookie); // 服务器返回给浏览器cookie以便下次判断
            }else {
                resultvo.setCode("1");
                // 在session对象中保存用户的登录状态
                resultvo.setMessage("登录成功");
                session.setAttribute("user", user);
            }
        }
        return resultvo;
    }
    /*设计注册接口-自己*/
//    @PostMapping("/regist")
//    //@ResponseBody
//    public ResultVo regist(String name, String password, String sex, java.sql.Date birthday, String capchar, MultipartFile file1, HttpSession session) throws IOException {
//        // 1. 处理验证码
//        final String captcha = (String) session.getAttribute("captcha");
//        System.out.println(capchar);
//        System.out.println(captcha);
//        final ResultVo resultvo = new ResultVo();
//        if (!(capchar!=null&&capchar.equals(captcha) )){
//            System.out.println("验证码错误");
//            // 返回错误消息，验证码错误
//            resultvo.setCode("-1");
//            resultvo.setMessage("验证码错误");
//        }else {
//            //1. 存放图片文件到指定的位置
//            //1.1 生成文件名
//            final String randomName = UUID.randomUUID().toString();
//            /*file.getOriginalFilename()是得到上传时的文件名*/
//            final String originalFilename = file1.getOriginalFilename();
//            /*获取文件名后缀*/
//             final String extension = FilenameUtils.getExtension(originalFilename);
//            String finalFileName = randomName+"."+ extension;
//            String finalFilePath = "D:\\imgCode" + File.separator + finalFileName;
//            System.out.println(("用户头像存放的路径-为{}" + finalFilePath));
//            /* 把内存图片写入磁盘中*/
//            //2. 把用户信息保存到数据库中
//            User user = new User();
//            /*// 利用spring的bean工具类实现属性拷贝
//            BeanUtils.copyProperties(userVo,user)*/
//            /*密码加密*/
//            Digester md5 = new Digester(DigestAlgorithm.MD5);
//            String pass = md5.digestHex(password);
//            user.setName(name);
//            user.setPassword(pass);
//
//            user.setSex(sex);
//            user.setBirthday(birthday);
//            /*user.setFilepath(finalFileName);*/
//            user.setRegistTime(new Date(System.currentTimeMillis()));
//            System.out.println(user);
//            log.debug("写入数据库的注册的用户信息为{}", user);
//            userService.addAutoIdUser(user);
//
//            file1.transferTo(new File(finalFilePath));
//            resultvo.setCode("0");
//
//            /*//3. 封装ResultVo对象并返回
//            resultVo = ResultVo.ok(user);*/
//        }
//        return resultvo;
//    }
//    /*设计注册接口-老师*/
    @PostMapping("/regist")
    public ResultVo regist(UserVo userVo, HttpSession session) throws Exception {
        final LineCaptcha captcha = (LineCaptcha) session.getAttribute(Constants.HUTOOL_SESSION_KEY);
        final String capchar = userVo.getCapchar();
        final ResultVo vo = new ResultVo();
        log.debug("入参为:userRegistVo={}",userVo);
        //查看数据库是否已存在用户名
        log.debug("入参为:userVo={}",userVo);
        User byName = userService.getByName(userVo.getName());
        if (byName==null) {
            // 1. 验证码校验
            if (capchar == null || !captcha.verify(capchar)) {
                log.debug("验证码错误:传入的验证码={},session中的验证码={}", capchar, captcha);
                vo.setCode("-1");
                vo.setMessage("验证码错误");
                return vo;
            }
            // 2. 调用service层的对象，完成具体的业务逻辑处理
            // 如果 userService.regist方法没有异常，就代表注册成功了，如果有异常，则抛出异常
            userService.regist(userVo);

            // 3. 根据service返回的结果，封装 ResultVo
            vo.setCode("0");
            vo.setMessage("注册成功");
            log.debug("注册成功");
            return vo;
        }else {
            vo.setCode("-1");
            vo.setMessage("用户名已存在，不可注册");
            return vo;
        }
    }
    @PostMapping("/checkname")
    public ResultVo checkname(String name) {
        final ResultVo vo = new ResultVo();
        //查看数据库是否已存在用户名
        log.debug("入参为:name={}",name);
        User byName = userService.getByName(name);
        if (byName!=null) {
            vo.setEx("1");
            vo.setCode("-1");
            log.debug("用户名已存在");
        }
        return vo;
    }
    /* @GetMapping(value = "/cj",produces= "text/html; charset=UTF-8")
     public String cj(String faire) {
         String name = null;
         if (faire.equals("ture")) {
             ArrayList<Cj> faire1 = userService.faire(0);
             int size = faire1.size();
             System.out.println(size);
             int id = (int) (Math.random()*size);
             System.out.println(id);
             Cj cj = faire1.get(id);
             cj.setStatus("1");
             System.out.println(cj.toString());
             name=cj.getName();
             System.out.println(userService.updateCj(cj)==1?"更新成功":"更新失败");
             System.out.println(name);
         }else if (faire.equals("false")){
             ArrayList<Cj> faire1 = userService.selectAllCj();
             int size = faire1.size();
             int id = (int) (Math.random()*size);
             Cj cj = faire1.get(id);
             name=cj.getName();
         }else {
             return  "参数错误";
         }
         return name;
     }*/
   /* @GetMapping(value = "/reset",produces= "text/json; charset=UTF-8")
    public String reset() {
        List  reset = new ArrayList();

    ArrayList<Cj> faire1 = userService.selectAllCj();
        ArrayList<Cj> faire1 = userService.faire(1);
        for (Cj cj : faire1) {
            cj.setStatus("0");
            String a=cj.getName()+"状态："+(userService.updateCj(cj)==1?"更新成功":"更新失败");
            reset.add(a);
        }
        System.out.println(reset);
        return "重置成功";
    }*/
    //老师的重置
    public ResultVo reset(){

        userService.reset();

//        final ResultVo resultVo = new ResultVo();
//        resultVo.setCode("1");
//        resultVo.setMessage("重置成功");

        return ResultVo.ok();

    }

    @GetMapping("/cache/draw")
    public ResultVo cachedraw(boolean fair){
        String username =  userService.cacheDraw(fair);
//        final ResultVo resultVo = new ResultVo();
//        resultVo.setCode("1");
//        resultVo.setMessage(username);
//        ResultVo ok = ResultVo.ok();
//        ok.setMessage(username);
        return ResultVo.ok(username);
    }



    @GetMapping("/draw")
    public ResultVo userdraw(boolean fair,HttpSession session){

        //如果用户登录过，则代码继续向下执行，如果没有登录，则直接返回错误的信息
        User user = (User) session.getAttribute("user");
        if (user==null){
            return ResultVo.error("用户没有登录，请重新登录");
        }

        String username =  userService.draw(fair);
        final ResultVo resultVo = new ResultVo();
        resultVo.setCode("1");
        resultVo.setMessage(username);
        return resultVo;

    }

}
